﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Configuration;

using NHibernate;
using NHibernate.Linq;
using System.Data.Entity;

using Ienablemuch.ToTheEfnhX;
using Ienablemuch.ToTheEfnhX.EntityFramework;
using Ienablemuch.ToTheEfnhX.NHibernate;



using TheEntities;



namespace TheService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Forumer : IForumer
    {


        public Forumer()
        {
        }

        IRepository<Question> QuestionRepository
        {
            get
            {
                // choose between these two

                int orm = 0; // 0 = Entity Framework, 1 = NHibernate


                if (orm == 0)
                {
                    // Entity Framework:
                    var x = new EfDbMapper();
                    return new EfRepository<Question>(x);
                }
                else if (orm == 1)
                {
                    // NHibernate:
                    return new NhRepository<Question>(NhDbMapper.GetSession(ConfigurationManager.ConnectionStrings["EfDbMapper"].ConnectionString));
                }
                else
                    throw new Exception("Please choose your ORM of choice");
            }
        }

        public Question OpenQuestion(int id)
        {
            var repo = QuestionRepository;

            var query = repo.All.Where(y => y.QuestionId == id);


            if (QuestionRepository.GetType() == typeof(EfRepository<Question>))
            {
                query = query
                        .Include("Answers")
                            .Include("Answers.Comments")
                        .Include("Comments");

                return query.Single();
            }
            else if (QuestionRepository.GetType() == typeof(NhRepository<Question>))
            {

                // * kinda sad, produces duplicate data

                /*
                query = query
                        .FetchMany(x => x.Answers)
                            .ThenFetchMany(x => x.Comments)
                        .FetchMany(x => x.Comments);
                */


                // Good thing there's Stackoverflow, here's one way to solve it:
                // http://stackoverflow.com/questions/7028705/is-nhibernate-fetchmany-on-more-than-two-tables-broken

                repo.All.Where(y => y.QuestionId == id)
                        .FetchMany(x => x.Answers)
                            .ThenFetchMany(x => x.Comments)
                        .ToFuture();

                query = repo.All.Where(y => y.QuestionId == id)
                        .FetchMany(x => x.Comments);




            }
            else
                throw new Exception("Something unsupported. Contact the developer");

            return query.Single();

        }


        public string GetData(int value)
        {

            // z.Database.Create();

            var x = QuestionRepository;

            return x.Get(1).Text;

            return string.Format("You entered: {0}", value);
        }



        public void SaveQuestion(Question question, out int id, out byte[] version)
        {
            var repo = QuestionRepository;
            repo.Merge(question, question.RowVersion);
            id = question.QuestionId;
            version = question.RowVersion;
        }



        public void DeleteQuestion(int questionId, byte[] version)
        {
            var repo = QuestionRepository;
            repo.DeleteCascade(questionId, version);
        }
    }
}
